Cython 2

Since the Cython notebook was created, the module, cython_import has been updated, extended and renamed to cython_compile

It can be used similar to cython_import but in addition it can be invoked via a pythonic decorator syntax.

Futhermore an experimental autodeclaration wrapper has been added

Python implementation


In [5]:
p = 32416190071 # large prime

In [6]:
import math
def pycheck(p):
    for y in xrange(2, int(math.sqrt(p)) + 1):
        if p % y == 0:
            return False
    return True
%timeit pycheck(p)


10 loops, best of 3: 44 ms per loop

Cython implementation in external module

Check the module cycheck.py

It contains three functions

  • cycheck: similar to pycheck above
  • cycheck_pure: similar to cycheck, but with pure variable declarations
  • cycheck_cdef: similar to cycheck, but with cdef variable delcarations

Run the script below and notice the difference


In [7]:
from cython_compile import cython_import
cython_import('cycheck')
import cycheck

%timeit pycheck(p)
%timeit cycheck.cycheck(p)
%timeit cycheck.cycheck_pure(p)
%timeit cycheck.cycheck_cdef(p)


10 loops, best of 3: 43.8 ms per loop
10 loops, best of 3: 37.8 ms per loop
1000 loops, best of 3: 1.31 ms per loop
1000 loops, best of 3: 1.31 ms per loop

So far the module is similar to the previous cython_import module, but in the next section the difference will become clear

Python function with decorator

No declarations


In [8]:
from cython_compile import cython_compile

@cython_compile
def pycheck(p):
    import math
    for y in xrange(2, int(math.sqrt(p)) + 1):
        if p % y == 0:
            return False
    return True
%timeit pycheck(p)


compiling ipythoninput8b8c820fa671b_pycheck: python.exe setup.py build_ext --inplace --compiler=mingw32
Compiling succeeded
1 loops, best of 3: 38.2 ms per loop

Pure declarations


In [9]:
import cython
from cython_compile import cython_compile

@cython_compile
@cython.ccall
@cython.locals(y=cython.int, p=cython.ulonglong)
def pycheck_pure(p):
    import math
    for y in xrange(2, int(math.sqrt(p)) + 1):
        if p % y == 0:
            return False
    return True
%timeit pycheck_pure(p)


compiling ipythoninput9572b104157e1_pycheck_pure: python.exe setup.py build_ext --inplace --compiler=mingw32
Compiling succeeded
1 loops, best of 3: 1.36 ms per loop

cdef declarations


In [10]:
from cython_compile import cython_compile

@cython_compile
def pycheck_cdef(p):  #cpdef pycheck_cdef(unsigned long long p):
    import math
    #cdef int y
    for y in xrange(2, int(math.sqrt(p)) + 1):
        if p % y == 0:
            return False
    return True
%timeit pycheck_cdef(p)


compiling ipythoninput10a0fe4c6a4ab1_pycheck_cdef: python.exe setup.py build_ext --inplace --compiler=mingw32
Compiling succeeded
1 loops, best of 3: 1.35 ms per loop

Auto declarations

A bit slower because p is declared as long long instead of unsigned long long


In [11]:
from cython_compile import cython_compile_autodeclare
@cython_compile_autodeclare
def pycheck(p):
    import math
    for y in xrange(2, int(math.sqrt(p)) + 1):
        if p % y == 0:
            return False
    return True
%timeit pycheck(17)


compiling ipythoninput11e49677a00e7c_pycheck: python.exe setup.py build_ext --inplace --compiler=mingw32
Compiling succeeded
1 loops, best of 3: 108 µs per loop

In [ ]: